/* Schema dependencies */

var Disease = require('../schema/DiseaseSchema').DiseaseSchema,
    Gene = require('../schema/GeneSchema').GeneSchema;

/**
 * Finds all Diseases that satisfy the given parameters.
 * See API documentation: GET /diseases/
 *
 * @param req  {HTTP Request}  : HTTP GET request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON array of Disease objects
 **/

exports.index = function(req, res) {
    var query = Disease.find().exclude('_id');
    
    // Limit by range
    if (req.query.range) {
        query.limit(req.query.range);
    }
    
    // Limit by family
    if (req.query.area) {
        query.where('area').equals(req.query.area);
    }

    // Use regular expressions to do a "contains" filter
    if (req.query.contains) {
        var regexFilter = new RegExp('.*' + req.query.contains + ".*");
        query.regex('name', regexFilter);
    }
    
    query.exec(function(err, disease) {
        // TODO: JSON error messages
        if (err) {
            console.log(err);
        } else {
            res.json(disease);
        } 
    });
};

/**
 * Creates a Disease object using the parameters found in the request body.
 * See API documentation: POST /diseases/
 *
 * @param req  {HTTP Request}  : HTTP POST request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON object representing success or error
 **/

exports.create = function(req, res) {

    // Create the Model
    var newDisease = new Disease(
        {
            id    : req.body.id,
            name  : req.body.name,
            area  : req.body.area,
            links : {
                genes : []
            }
        }
    );
    
    // Save the Model in the database
    newDisease.save(function(err) {
        // TODO: JSON error messages
        if (err) {
            console.log(err);
        } else {
            var returnBody = {
                success : true,
                id      : newDisease.id,
                code    : 100,
                message : "Disease successfully added to the database."
            };
            res.json(returnBody);
        }
    });
};

/**
 * Finds a single Disease object with the given disease ID.
 * See API documentation: GET /diseases/[id]
 *
 * @param req  {HTTP Request}  : HTTP GET request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON representation of desired Disease object
 **/

exports.show = function(req, res) {
    var query = Disease.findOne()
        .where('id').equals(req.params.disease)
        .exclude('_id');
    query.exec(function(err, disease) {
        // TODO: JSON error messages
        if (err) { 
            console.log(err);
        } else if (!disease) {
            var nullDisease = {
                success: false,
                code: 101,
                message: "Disease #" + req.params.disease + " not found in database."
            };
            res.json(nullDisease, 404);
        } else { 
            res.json(disease);
        }
    });
};

/**
 * Updates a single Disease object with the given disease ID.
 * Accepts partial representations of the Disease object.
 * See API documentation: PUT /diseases/[id]
 *
 * @param req  {HTTP Request}  : HTTP PUT request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON object representing success or error.
 **/

exports.update = function(req, res) {
    var updatedDoc = {};

    if (req.body.name) { 
        updatedDoc.name = req.body.name;
    }
    if (req.body.area) { 
        updatedDoc.area = req.body.area; 
    }
    if (req.body.gene) {
        Gene.findOne({id: req.body.gene}, function(err, gene) {
            gene.links.diseases.push(req.params.disease);
            gene.save(function(err) {
                if (err) {
                    console.log(err);
                } else {
                    Disease.findOne({id: req.params.disease}, function(err, disease) {
                        disease.links.genes.push(req.body.gene);
                        disease.save(function(err) {
                            if (err) {
                                console.log(err);
                            }
                        });
                    });
                }
            });
        });
    }

    Disease.update({id: req.params.disease}, updatedDoc, function(err) {
        if (err) {
            // TODO: JSON error messages
            console.log(err);
        } else {
            var returnBody = {
                success : true,
                code    : 200,
                message : "Disease successfully updated in the database."
            };
            res.json(returnBody);
        }
    });
};

/**
 * Deletes a single Disease object with the given disease ID.
 * See API documentation: DELETE /diseases/[id]
 *
 * @param req  {HTTP Request}  : HTTP DELETE request passed from the route
 * @param res  {HTTP Response} : Waiting HTTP response passed from the route
 *
 * @response {JSON Object}     : JSON object representing success or error.
 **/

exports.destroy = function(req, res) {
    Gene.findOne({id: req.params.gene}, function(err, gene) {
        var i;
        var diseases = gene.links.diseases;
        for (i = 0; i < diseases.length; i++) {
            if (diseases[i].id == req.params.disease) {
                gene.links.diseases[i].remove();
                gene.save(function(err) {
                    if (err) {
                        console.log(err);
                    } else {
                        var returnBody = {
                            success : true,
                            code    : 300,
                            message : "Disease successfully deleted from the database."
                        };
                        res.json(returnBody);
                    }
                });
                break;
            }
        }
    });
};
